---
title: "Dropdown"
description: "Displays a list of actions or options that a user can choose."
---

import {dropdownContent} from "@/content/components/dropdown";

# Dropdown

Displays a list of actions or options that a user can choose.

<ComponentLinks component="dropdown" reactAriaHook="useMenu" />

---

<CarbonAd/>

## Installation

<PackageManagers
  showGlobalInstallWarning
  commands={{
    cli: "npx heroui-cli@latest add dropdown",
    npm: "npm install @heroui/dropdown",
    yarn: "yarn add @heroui/dropdown",
    pnpm: "pnpm add @heroui/dropdown",
    bun: "bun add @heroui/dropdown"
  }}
/>


## Import

HeroUI exports 5 dropdown-related components:

- **Dropdown**: The main component, which is a wrapper for the other components. This component is an extension of the [Popover](/docs/components/popover) component, so it accepts all the props of the Popover component.
- **DropdownTrigger**: The component that triggers the dropdown menu to open.
- **DropdownMenu**: The component that contains the dropdown items.
- **DropdownSection**: The component that contains a group of dropdown items.
- **DropdownItem**: The component that represents a dropdown item.

<ImportTabs
  commands={{
    main: `import {
    Dropdown,
    DropdownTrigger,
    DropdownMenu,
    DropdownSection,
    DropdownItem
} from "@heroui/react";`,
    individual: `import {
    Dropdown,
    DropdownTrigger,
    DropdownMenu,
    DropdownSection,
    DropdownItem
} from "@heroui/dropdown";`,
  }}
/>

## Usage

<CodeDemo title="Usage" files={dropdownContent.usage} />

### Dynamic items

Dropdown follows the [Collection Components API](https://react-spectrum.adobe.com/react-stately/collections.html), accepting both static and dynamic collections.

- **Static**: The usage example above shows the static implementation, which can be used when the full list of options is known ahead of time.
- **Dynamic**: The example below can be used when the options come from an external data source such as an API call, or update over time.

<CodeDemo title="Dynamic items" files={dropdownContent.dynamic} />

### Disabled Keys

Dropdown items can be disabled using the `disabledKeys` prop to the `DropdownMenu` component.

<CodeDemo title="Disabled Keys" files={dropdownContent.disabledKeys} />

> **Note**: It's important to have a unique key for each item, otherwise the disabled keys will not work.

### Action event

You can use the `onAction` prop to get the key of the selected item.

<CodeDemo title="Action event" files={dropdownContent.action} />

### Variants

You can use the `variant` in the `DropdownMenu` component to change the `hover` style of the dropdown items.

<CodeDemo title="Variants" files={dropdownContent.variants} />

### Single Selection

You can set the `selectionMode` property as `single` to allow the user to select only one item at a time.

<CodeDemo
  title="Single Selection"
  files={dropdownContent.singleSelection}
/>

### Multiple Selection

You can set the `selectionMode` property as `multiple` to allow the user to select multiple items at a time.

<CodeDemo
  title="Multiple Selection"
  files={dropdownContent.multipleSelection}
/>

> **Note**: To allow empty selection, you can set the `disallowEmptySelection` property as `false`.

### With Shortcut

You can use the `shortcut` prop to add a shortcut to the dropdown item.

<CodeDemo title="With Shortcut" files={dropdownContent.shortcut} />

> **Note**: Dropdown does not handle the shortcut event, you need to handle it yourself.

### With Icons

It is possible to add icons to the dropdown items using the `startContent` / `endContent` props.

<CodeDemo title="With Icons" files={dropdownContent.icons} />

> **Note**: If you use `currentColor` as the icon color, the icon will have the same color as the item text.

### With Description

You can use the `description` prop to add a description to the dropdown item.

<CodeDemo
  title="With Description"
  files={dropdownContent.description}
/>

### With Sections

You can use the `DropdownSection` component to group dropdown items.

<CodeDemo title="With Sections" files={dropdownContent.sections} />

> **Note**: Sections without a `title` must provide an `aria-label` for accessibility.

### Custom Trigger

You can use any component as a trigger for the dropdown menu, just wrap it in the `DropdownTrigger` component.

<CodeDemo title="Custom Trigger" files={dropdownContent.customTrigger} />

### Changing the backdrop

As we mentioned earlier, the `Dropdown` component is an extension of the [Popover](/docs/components/popover) component,
so it accepts all the props of the Popover component, including the `backdrop` prop.

<CodeDemo title="Changing the backdrop" files={dropdownContent.backdrop} />

### Routing

The `<DropdownItem>` component works with frameworks and client side routers like [Next.js](https://nextjs.org/) and
[React Router](https://reactrouter.com/en/main). See the [Routing](/docs/guide/routing) guide to learn how to set this up.

```jsx
import {Dropdown, DropdownMenu, DropdownTrigger, DropdownItem, Button} from "@heroui/react";

function App() {
  return (
    <Dropdown>
      <DropdownTrigger>
        <Button variant="bordered">Open Menu</Button>
      </DropdownTrigger>
      <DropdownMenu aria-label="Link Actions">
        <DropdownItem key="home" href="/home">
          Home
        </DropdownItem>
        <DropdownItem key="about" href="/about">
          About
        </DropdownItem>
      </DropdownMenu>
    </Dropdown>
  );
}
```

## Slots

Dropdown has 3 components with slots the `DropdownMenu`, `DropdownItem` and `DropdownSection` components.

### DropdownMenu

- **base**: The main wrapper for the menu component. This slot wraps the `topContent`, `bottomContent` and the `list` slot.
- **list**: The slot for the menu list component. You can see this slot as the `ul` slot.
- **emptyContent**: The slot content to display when the collection is empty.

### DropdownItem

- **base**: The main slot for the dropdown item. It wraps all the other slots.
- **wrapper**: The `title` and `description` wrapper.
- **title**: The title of the dropdown item.
- **description**: The description of the dropdown item.
- **shortcut**: The shortcut slot.
- **selectedIcon**: The selected icon slot. This is only visible when the item is selected.

### DropdownSection

- **base**: The main slot for the dropdown section. It wraps all the other slots.
- **heading**: The title that is render on top of the section group.
- **group**: The group of dropdown items.
- **divider**: The divider that is render between the groups. This is only visible when `showDivider` is `true`.

### Customizing the dropdown popover

The `Dropdown` component is an extension of the [Popover](/docs/components/popover) component, so you can use the same
slots to customize the dropdown.

<CodeDemo
  title="Custom Popover Styles"
  files={dropdownContent.customPopoverStyles}
/>

### Customizing the dropdown items style

You can customize the dropdown items either by using the `DropdownMenu` `itemClasses` prop or by using the
`DropdownItem` slots, the `itemClasses` allows you to customize all the items at once, while the slots allow
you to customize each item individually.

<CodeDemo title="Custom Dropdown Items Styles" files={dropdownContent.customItemsStyles} />

<Spacer y={4} />

### Keyboard Interactions

| Key                              | Description                                                                                                                                   |
| -------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
| <Kbd>Space</Kbd>                 | When focus is on `DropdownTrigger`, opens the dropdown menu and focuses the first item. When focus is on an item, activates the focused item. |
| <Kbd>Enter</Kbd>                 | When focus is on `DropdownTrigger`, opens the dropdown menu and focuses the first item. When focus is on an item, activates the focused item. |
| <Kbd>ArrowDown</Kbd>             | When focus is on `DropdownTrigger`, opens the dropdown menu. When focus is on an item, moves focus to the next item.                          |
| <Kbd>ArrowUp</Kbd>               | When focus is on an item, moves focus to the previous item.                                                                                   |
| <Kbd>Esc</Kbd>                   | Closes the dropdown menu and moves focus to `DropdownTrigger`.                                                                                |
| <Kbd>A-Z</Kbd> or <Kbd>a-z</Kbd> | When the menu is open, moves focus to the next menu item with a label that starts with the typed character if such an menu item exists.       |

<Spacer y={4} />

## Data Attributes

`DropdownItem` has the following attributes on the `base` element:

- **data-disabled**:
  When the dropdown item is disabled. Based on dropdown `disabledKeys` prop.
- **data-selected**:
  When the dropdown item is selected. Based on dropdown `selectedKeys` prop.
- **data-hover**:
  When the dropdown item is being hovered. Based on [useHover](https://react-spectrum.adobe.com/react-aria/useHover.html)
- **data-pressed**:
  When the dropdown item is pressed. Based on [usePress](https://react-spectrum.adobe.com/react-aria/usePress.html)
- **data-focus**:
  When the dropdown item is being focused. Based on [useFocusRing](https://react-spectrum.adobe.com/react-aria/useFocusRing.html).
- **data-focus-visible**:
  When the dropdown item is being focused with the keyboard. Based on [useFocusRing](https://react-spectrum.adobe.com/react-aria/useFocusRing.html).

<Spacer y={4} />

## Accessibility

- Exposed to assistive technology as a `button` with a `menu` using ARIA.
- Support for single, multiple, or no selection.
- Support for disabled items.
- Support for sections.
- Complex item labeling support for accessibility.
- Keyboard navigation support including arrow keys, home/end, page up/down. See [Keyboard Interactions](#keyboard-interactions) for more details.
- Automatic scrolling support during keyboard navigation.
- Keyboard support for opening the menu using the arrow keys, including automatically focusing the first or last item accordingly.
- Typeahead to allow focusing items by typing text.
- Virtualized scrolling support for performance with long lists.

<Spacer y={4} />

## API

### Dropdown Props

<APITable
  data={[
    {
      attribute: "children*",
      type: "ReactNode[]",
      description: "The children to render. Usually a DropdownTrigger and DropdownMenu elements.",
      default: "-"
    },
    {
      attribute: "type",
      type: "menu | listbox",
      description: "Type of overlay that is opened by the dropdown trigger.",
      default: "menu"
    },
    {
      attribute: "trigger",
      type: "press | longPress",
      description: "How the dropdown menu is triggered.",
      default: "press"
    },
    {
      attribute: "isDisabled",
      type: "boolean",
      description: "Whether the dropdown trigger is disabled.",
      default: "false"
    },
    {
      attribute: "closeOnSelect",
      type: "boolean",
      description: "Whether the dropdown menu should be closed when an item is selected.",
      default: "true"
    },
    {
      attribute: "shouldBlockScroll",
      type: "boolean",
      description: "Whether the dropdown menu should block scrolling outside the menu.",
      default: "true"
    },
    {
      attribute: "PopoverProps",
      type: "PopoverProps",
      description: "Since the dropdown is an extension of the popover, it accepts all the props of the popover component.",
      default: "-"
    }
  ]}
/>

### Dropdown Events

<APITable
  data={[
    {
      attribute: "onOpenChange",
      type: "(isOpen: boolean) => void",
      description: "Handler that is called when the dropdown's open state changes.",
      default: "-"
    },
    {
      attribute: "shouldCloseOnInteractOutside",
      type: "(e: HTMLElement) => void",
      description: "When user interacts with the argument element outside of the dropdown ref, return true if onClose should be called.",
      default: "-"
    },
    {
      attribute: "onClose",
      type: "() => void",
      description: "Handler that is called when the dropdown should close.",
      default: "-"
    }
  ]}
/>

### DropdownTrigger Props

<APITable
  data={[
    {
      attribute: "children",
      type: "ReactNode",
      description: "The dropdown trigger component, ensure the children passed is focusable. Users can tab to it using their keyboard, and it can take a ref. It is critical for accessibility.",
      default: "-"
    }
  ]}
/>

### DropdownMenu Props

<APITable
  data={[
    {
      attribute: "children*",
      type: "ReactNode | ((item: T) => ReactElement)",
      description: "The contents of the collection. It's usually the DropdownItem or DropdownSection. (static)",
      default: "-"
    },
    {
      attribute: "items",
      type: "Iterable<T>",
      description: "Item objects in the collection. (dynamic)",
      default: "-"
    },
    {
      attribute: "variant",
      type: "solid | bordered | light | flat | faded | shadow",
      description: "The dropdown items appearance style.",
      default: "solid"
    },
    {
      attribute: "color",
      type: "default | primary | secondary | success | warning | danger",
      description: "The dropdown items color theme.",
      default: "default"
    },
    {
      attribute: "selectionMode",
      type: "none | single | multiple",
      description: "The type of selection that is allowed in the collection.",
      default: "-"
    },
    {
      attribute: "selectedKeys",
      type: "all | Iterable<React.Key>",
      description: "The currently selected keys in the collection (controlled).",
      default: "-"
    },
    {
      attribute: "disabledKeys",
      type: "Iterable<React.Key>",
      description: "The item keys that are disabled. These items cannot be selected, focused, or otherwise interacted with.",
      default: "-"
    },
    {
      attribute: "defaultSelectedKeys",
      type: "all | Iterable<React.Key>",
      description: "The initial selected keys in the collection (uncontrolled).",
      default: "-"
    },
    {
      attribute: "disallowEmptySelection",
      type: "boolean",
      description: "Whether the collection allows empty selection.",
      default: "false"
    },
    {
      attribute: "autoFocus",
      type: "boolean | first | last",
      description: "Where the focus should be set.",
      default: "false"
    },
    {
      attribute: "topContent",
      type: "ReactNode",
      description: "The content to display above the listbox items.",
      default: "-"
    },
    {
      attribute: "bottomContent",
      type: "ReactNode",
      description: "The content to display below the listbox items.",
      default: "-"
    },
    {
      attribute: "emptyContent",
      type: "ReactNode",
      description: "The content to display when the collection is empty.",
      default: "No items."
    },
    {
      attribute: "hideEmptyContent",
      type: "boolean",
      description: "Whether to not display the empty content when the collection is empty.",
      default: "false"
    },
    {
      attribute: "hideSelectedIcon",
      type: "boolean",
      description: "Whether to hide the check icon when the items are selected.",
      default: "false"
    },
    {
      attribute: "shouldFocusWrap",
      type: "boolean",
      description: "Whether keyboard navigation is circular.",
      default: "false"
    },
    {
      attribute: "closeOnSelect",
      type: "boolean",
      description: "Whether the dropdown menu should be closed when an item is selected.",
      default: "true"
    },
    {
      attribute: "disableAnimation",
      type: "boolean",
      description: "Whether to disable the animation of the dropdown items.",
      default: "false"
    },
    {
      attribute: "classNames",
      type: "Partial<Record<'base'｜'list'｜'emptyContent', string>>",
      description: "Allows to set custom class names for the dropdown menu slots.",
      default: "-"
    },
    {
      attribute: "itemClasses",
      type: "Partial<Record<'base'｜'wrapper'｜'title'｜'description'｜'shortcut'｜'selectedIcon', string>>",
      description: "Allows to set custom class names for the dropdown item slots.",
      default: "-"
    }
  ]}
/>

### DropdownMenu Events

<APITable
  data={[
    {
      attribute: "onAction",
      type: "(key: React.Key) => void",
      description: "Handler that is called when an item is selected.",
      default: "-"
    },
    {
      attribute: "onSelectionChange",
      type: "(keys: \"all\" | Set<React.Key> & {anchorKey?: string; currentKey?: string}) => void",
      description: "Handler that is called when the selection changes.",
      default: "-"
    },
    {
      attribute: "onClose",
      type: "() => void",
      description: "Handler that is called when the menu should close after selecting an item.",
      default: "-"
    }
  ]}
/>

### DropdownSection Props

<APITable
  data={[
    {
      attribute: "children*",
      type: "ReactNode",
      description: "The contents of the dropdown section. Usually a list of DropdownItem components. (static)",
      default: "-"
    },
    {
      attribute: "title",
      type: "string",
      description: "The title of the dropdown section.",
      default: "-"
    },
    {
      attribute: "items",
      type: "Iterable<T>",
      description: "Item objects in the collection. (dynamic)",
      default: "-"
    },
    {
      attribute: "hideSelectedIcon",
      type: "boolean",
      description: "Whether to hide the check icon when the items are selected.",
      default: "false"
    },
    {
      attribute: "showDivider",
      type: "boolean",
      description: "Whether to show the divider between the groups.",
      default: "false"
    },
    {
      attribute: "dividerProps",
      type: "DividerProps",
      description: "The divider component props.",
      default: "-"
    },
    {
      attribute: "classNames",
      type: "Record<'base'｜'heading'｜'group'｜'divider', string>>",
      description: "Allows to set custom class names for the dropdown section slots.",
      default: "-"
    },
    {
      attribute: "itemClasses",
      type: "Record<'base'｜'wrapper'｜'title'｜'description'｜'shortcut'｜'selectedIcon', string>>",
      description: "Allows to set custom class names for the dropdown item slots.",
      default: "-"
    }
  ]}
/>

### DropdownItem Props

<APITable
  data={[
    {
      attribute: "children*",
      type: "ReactNode",
      description: "The contents of the dropdown item.",
      default: "-"
    },
    {
      attribute: "key",
      type: "React.Key",
      description: "The unique key for the dropdown item.",
      default: "-"
    },
    {
      attribute: "title",
      type: "string | ReactNode",
      description: "The title of the dropdown item.",
      default: "-"
    },
    {
      attribute: "textValue",
      type: "string",
      description: "A string representation of the item's contents, used for features like typeahead.",
      default: "-"
    },
    {
      attribute: "description",
      type: "string | ReactNode",
      description: "The description of the dropdown item.",
      default: "-"
    },
    {
      attribute: "shortcut",
      type: "string | ReactNode",
      description: "The dropdown item keyboard shortcut.",
      default: "-"
    },
    {
      attribute: "startContent",
      type: "ReactNode",
      description: "The start content of the dropdown item.",
      default: "-"
    },
    {
      attribute: "endContent",
      type: "ReactNode",
      description: "The end content of the dropdown item. This is positioned after the shortcut and the selected icon.",
      default: "-"
    },
    {
      attribute: "selectedIcon",
      type: "SelectedIconProps",
      description: "Custom icon to render when the item is selected.",
      default: "-"
    },
    {
      attribute: "showDivider",
      type: "boolean",
      description: "Whether to show a divider below the item.",
      default: "false"
    },
    {
      attribute: "href",
      type: "string",
      description: "A URL to link to. See MDN.",
      default: "-"
    },
    {
      attribute: "target",
      type: "HTMLAttributeAnchorTarget",
      description: "The target window for the link. See MDN.",
      default: "-"
    },
    {
      attribute: "rel",
      type: "string",
      description: "The relationship between the linked resource and the current page. See MDN.",
      default: "-"
    },
    {
      attribute: "download",
      type: "boolean | string",
      description: "Causes the browser to download the linked URL. A string may be provided to suggest a file name. See MDN.",
      default: "-"
    },
    {
      attribute: "ping",
      type: "string",
      description: "A space-separated list of URLs to ping when the link is followed. See MDN.",
      default: "-"
    },
    {
      attribute: "referrerPolicy",
      type: "HTMLAttributeReferrerPolicy",
      description: "How much of the referrer to send when following the link. See MDN.",
      default: "-"
    },
    {
      attribute: "isDisabled",
      type: "boolean",
      description: "Whether the dropdown item should be disabled. (Deprecated) pass disabledKeys to DropdownMenu instead.",
      default: "false"
    },
    {
      attribute: "isSelected",
      type: "boolean",
      description: "Whether the dropdown item should be selected. (Deprecated) pass selectedKeys to DropdownMenu instead.",
      default: "false"
    },
    {
      attribute: "isReadOnly",
      type: "boolean",
      description: "Whether the dropdown item press events should be ignored.",
      default: "false"
    },
    {
      attribute: "hideSelectedIcon",
      type: "boolean",
      description: "Whether to hide the check icon when the item is selected.",
      default: "false"
    },
    {
      attribute: "closeOnSelect",
      type: "boolean",
      description: "Whether the dropdown menu should be closed when the item is selected.",
      default: "true"
    },
    {
      attribute: "classNames",
      type: "Record<'base'｜'wrapper'｜'title'｜'description'｜'shortcut'｜'selectedIcon', string>>",
      description: "Allows to set custom class names for the dropdown item slots.",
      default: "-"
    }
  ]}
/>

### DropdownItem Events

<APITable
  data={[
    {
      attribute: "onAction",
      type: "() => void",
      description: "Handler that is called when the dropdown item is selected. (Deprecated) pass to DropdownMenu instead.",
      default: "-"
    },
    {
      attribute: "onClose",
      type: "() => void",
      description: "Handler that is called when the dropdown item should close after selecting. (Deprecated) pass to DropdownMenu instead.",
      default: "-"
    },
    {
      attribute: "onPress",
      type: "(e: PressEvent) => void",
      description: "Handler called when the press is released over the target.",
      default: "-"
    },
    {
      attribute: "onPressStart",
      type: "(e: PressEvent) => void",
      description: "Handler called when a press interaction starts.",
      default: "-"
    },
    {
      attribute: "onPressEnd",
      type: "(e: PressEvent) => void",
      description: "Handler called when a press interaction ends, either over the target or when the pointer leaves the target.",
      default: "-"
    },
    {
      attribute: "onPressChange",
      type: "(isPressed: boolean) => void",
      description: "Handler called when the press state changes.",
      default: "-"
    },
    {
      attribute: "onPressUp",
      type: "(e: PressEvent) => void",
      description: "Handler called when a press is released over the target, regardless of whether it started on the target or not.",
      default: "-"
    },
    {
      attribute: "onKeyDown",
      type: "(e: KeyboardEvent) => void",
      description: "Handler called when a key is pressed.",
      default: "-"
    },
    {
      attribute: "onKeyUp",
      type: "(e: KeyboardEvent) => void",
      description: "Handler called when a key is released.",
      default: "-"
    },
    {
      attribute: "onClick",
      deprecated: true,
      type: "MouseEventHandler",
      description: "The native button click event handler (**Deprecated**) use **onPress** instead.",
      default: "-"
    }
  ]}
/>

### Types

#### Dropdown Item Selected Icon Props

```ts
export type DropdownItemSelectedIconProps = {
  /**
   * The current icon, usually an checkmark icon.
   */
  icon?: ReactNode;
  /**
   * The current selected status.
   */
  isSelected?: boolean;
  /**
   * The current disabled status.
   * @default false
   */
  isDisabled?: boolean;
};

type selectedIcon?: ReactNode | ((props: DropdownItemSelectedIconProps) => ReactNode) | null;
```
